package com.xzakota.minesweeper.ui.dialog.templae;

import com.xzakota.minesweeper.log.XLogger;
import com.xzakota.minesweeper.widget.image.LoadingImage;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
 * 使用 SwingWorker 工作的等待对话框
 *
 * @author Xzakota
 */
public class SwingWorkerWaitDialog extends AbstractBaseDialog {
    private final JLabel tipLabel;
    public Thread tempThread;
    public Worker worker;
    private InnerSwingWorker swingWorker;

    public SwingWorkerWaitDialog() {
        super();
        setTitle("提示");

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));

        LoadingImage loadingImage = new LoadingImage(true);
        mainPanel.add(loadingImage);

        tipLabel = new JLabel();
        tipLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        mainPanel.add(Box.createVerticalStrut(10));
        setTipText("正在加载中...");
        mainPanel.add(tipLabel);

        setComponent(mainPanel);

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                closeWindow();
            }

            @Override
            public void windowClosed(WindowEvent e) {
                super.windowClosed(e);
                doReleaseEvent();
            }
        });
    }

    public void setTipText(String text) {
        tipLabel.setText(text);
    }

    @Override
    public void showWindow() {
        swingWorker = new InnerSwingWorker();
        swingWorker.execute();

        super.showWindow();
    }

    @Override
    public void closeWindow() {
        doReleaseEvent();

        super.closeWindow();

        if (swingWorker != null && !swingWorker.isDone()) {
            swingWorker.cancel(true);
        }
    }

    public void doReleaseEvent() {
        if (tempThread != null) {
            tempThread.interrupt();
            tempThread = null;
        }
    }

    public static abstract class Worker {
        abstract public Boolean doInBackground();

        abstract public void doneSuccess();

        abstract public void doneFail();
    }

    private class InnerSwingWorker extends SwingWorker<Boolean, Void> {
        @Override
        protected Boolean doInBackground() throws Exception {
            if (worker != null) {
                return worker.doInBackground();
            }
            return false;
        }

        @Override
        protected void done() {
            super.done();

            try {
                boolean result = !isCancelled() && get();
                closeWindow();

                if (worker != null) {
                    if (result) {
                        worker.doneSuccess();
                    } else {
                        worker.doneFail();
                    }
                }
            } catch (Exception e) {
                XLogger.error(e);
            }
        }
    }

}
